package com.example.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.jwt.JWT;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.Dto.*;
import com.example.SMS.SMSUtils;
import com.example.Vo.LikeEachOtherVo;
import com.example.Vo.LoginVo;
import com.example.Vo.UserAnswerVo;
import com.example.mapper.UserMapper;

import com.example.pojo.User;
import com.example.pojo.UserAnswerProblem;
import com.example.pojo.UserLike;
import com.example.service.UserService;
import com.example.thread.UserThreadLocal;
import lombok.extern.slf4j.Slf4j;


import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;


/**
 * @author liguoping
 */
@Service
@Slf4j
public class UserServiceImpl implements UserService {
    @Resource
    private UserMapper userMapper;
    @Resource
    private RedisTemplate<String, String> redisTemplate;


    @Override
    public boolean sendMsg(UserDto userDto) {
        //  1：生成验证码
        Random random = new Random();
        int number = random.nextInt(899999) + 100000;

        //  通过阿里云发送短信
        SMSUtils.sendMessage("阿里云短信测试", "SMS_154950909", userDto.getPhone(), String.valueOf(number));
        //  2：通过redis的set写入数据
        redisTemplate.opsForValue().set("CODE" + userDto.getPhone(), "" + number, 30, TimeUnit.MINUTES);

        return true;
    }

    @Override
    public LoginVo login(UserCodeDto userCodeDto) {
        //  1：校验入参
        if (userCodeDto == null
                || StrUtil.isBlank(userCodeDto.getCode())
                || StrUtil.isBlank(userCodeDto.getPhone())) {
            throw new RuntimeException("参数不能为空");
        }

        //  2：校验验证码
        String phone = userCodeDto.getPhone();

        //  2-1 从redis中获取验证码
        String codeRedis = redisTemplate.opsForValue().get("CODE" + phone);

        //  2-2 从用户获取验证码
        String code = userCodeDto.getCode();

        //  2-3 比较验证码
        if (!code.equals(codeRedis)) {
            throw new RuntimeException("验证码不一致");
        }
        //  0：老用户   1：新用户
        int status = 0;

        //  3 :判断是否为新用户，如为新用户则创建新用户
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getPhone, phone);
        User user = userMapper.selectOne(wrapper);
        if (user == null) {
            User users = new User();
            users.setId(IdUtil.getSnowflakeNextIdStr());
            users.setPhone(phone);
            users.setStatus(0);
            int insert = userMapper.insert(users);
            if (insert == 0) {
                throw new RuntimeException("新建用户失败");
            }
            status = 1;
        }
        //  4： 生成token
        String token = JWT.create()
                //载荷不允许敏感信息
                //载荷开始
                //必选
                .setPayload("adminId", "管理员id")
                //可选
                .setPayload("name", "管理昵称")
                //载荷结束
                //key保密不可放出，否则爆炸
                .setKey("yrh0203".getBytes())
                .sign();
        //  5： 组装vo返回
        LoginVo loginVo = new LoginVo();
        loginVo.setToken(token);
        loginVo.setStatus(status);
        return loginVo;
    }

    @Override
    public boolean updateUser(User user) throws ParseException {
        if (StringUtils.isEmpty(user)) {
            throw new RuntimeException("参数为空！！");
        }
        Date date = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        //  把用户输入的生日转换成对应的时间戳
        long startTime = simpleDateFormat.parse(user.getBirthday()).getTime();

        //  simpleDateFormat.format将系统时间转换为指定格式（"yyyy-MM-dd"）,然后再转换成对应的时间戳
        long age1 = simpleDateFormat.parse(simpleDateFormat.format(date)).getTime();

        //  通过时间戳做差，差的值，计算成年数，则为年龄
        long age3 = (age1 - startTime) / 1000;
        int age4 = (int) (age3 / (365 * 24 * 60 * 60));
//        System.out.println("您的年龄是："+age4);
        user.setAge(age4);
        user.setCreateUser(user.getName());
        String id = UserThreadLocal.get();
        boolean res = userMapper.updateUser(user, id);
        if (res) {
            return true;
        }
        throw new RuntimeException("修改失败");
    }

    @Override
    public boolean updatePhoneSendMsg(UserCodeDto userCodeDto) {

//  1：校验入参
        if (userCodeDto == null || StringUtils.isEmpty(userCodeDto.getCode()) || StringUtils.isEmpty(userCodeDto.getPhone())) {
            throw new RuntimeException("参数不能为空");
        }
        //  2：校验验证码
        String phone = userCodeDto.getPhone();

        //  2-1 从redis中获取验证码
        String codeRedis = redisTemplate.opsForValue().get("CODE" + phone);

        //  2-2 从用户获取验证码
        String code = userCodeDto.getCode();

        //  2-3 比较验证码
        if (!code.equals(codeRedis)) {
            throw new RuntimeException("验证码不一致");
        }
        return true;
    }

    @Override
    public boolean updatePhone(String NewPhone) {
        //  从请求头获取id
        String id = UserThreadLocal.get();
        //  通过id修改新的手机号
        boolean res = userMapper.updatePhone(NewPhone, id);
        if (!res) {
            throw new RuntimeException("修改手机号失败！");
        }
        //  清除
        UserThreadLocal.remove();
        return true;
    }

    @Override
    public boolean addProblem(UserProblemDto userProblemDto) {
        //获取回答者id
        String id = UserThreadLocal.get();
        return userMapper.addProblem(userProblemDto.getProblem(), id);
    }

    @Override
    public boolean addAnswerProblem(UserAnswerProblemDto userAnswerProblemDto) {
        //获取回答者id
        String id = UserThreadLocal.get();

        //创建一个细对象
        UserAnswerProblem userAnswerProblem = new UserAnswerProblem();

        //把dto的数据复制给po
        BeanUtils.copyProperties(userAnswerProblemDto, userAnswerProblem);

        //userId是回答者id   newUserId  目标id
        userAnswerProblem.setNewUserId(id);

        //雪花id
        userAnswerProblem.setId(IdUtil.getSnowflakeNextIdStr());

        //获取用户信息
        User user = findUser(id);

        //注入用户昵称
        userAnswerProblem.setCreateUser(user.getName());

        //把数据存入数据库
        return userMapper.addAnswerProblem(userAnswerProblem);
    }

    //通过id查询用户
    private User findUser(String id) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getId, id);
        return userMapper.selectOne(wrapper);

    }

    @Override
    public UserAnswerVo findAnswerProblemById() {
        String id = UserThreadLocal.get();
        return userMapper.findAnswerProblenById(id);
    }

    @Override
    public boolean updateInstall(Integer like, Integer comment, Integer announcement) {
        String id = UserThreadLocal.get();
        User user = findUser(id);
        return userMapper.updateInstall(like, comment, announcement, id, user.getName());
    }

    @Override
    public boolean setLike(UserLikeDto userLikeDto) {
        //获取此用户id
        String id = UserThreadLocal.get();

        //创建一个新对象
        UserLike userLike = new UserLike();

        //将喜欢这的id复制到新对象中
        BeanUtils.copyProperties(userLikeDto, userLike);

        //雪花id
        userLike.setId(IdUtil.getSnowflakeNextIdStr());

        //插入创建用户的id
        userLike.setCreateUser(id);

        //插入用户的id
        userLike.setUserId(id);

        return userMapper.setLike(userLike);
    }

    @Override
    public List<LikeEachOtherVo> getLikeEachOther(String id) {
        //查询互相喜欢
        return userMapper.getLikeEanOther(id);
    }

    @Override
    public boolean cancelLike(String likeId) {
        //获取用户id
        String userId = UserThreadLocal.get();
        //取消喜欢          传入用户id，被取消喜欢id
        return userMapper.cancelLike(userId, likeId);
    }

    @Override
    public List<LikeEachOtherVo> getLike() {
        //获取用户id
        String userId = UserThreadLocal.get();
        //获取喜欢列表
        return userMapper.getLike(userId);
    }

    @Override
    public List<LikeEachOtherVo> getFans() {
        //获取用户id
        String userId = UserThreadLocal.get();
        //获取粉丝列表
        return userMapper.getFans(userId);
    }


}
